import cv2
import skimage.io
import skimage.filters
import pandas as pd
from skimage.feature import (greycomatrix, greycoprops)
import numpy as np

def fractal_dimension(Z, threshold=0.9):
    # Only for 2d image
    assert (len(Z.shape) == 2)

    # From https://github.com/rougier/numpy-100 (#87)
    def boxcount(Z, k):
        S = np.add.reduceat(
            np.add.reduceat(Z, np.arange(0, Z.shape[0], k), axis=0),
            np.arange(0, Z.shape[1], k), axis=1)

        # We count non-empty (0) and non-full boxes (k*k)
        return len(np.where((S > 0) & (S < k * k))[0])

    # Transform Z into a binary array
    Z = (Z < threshold)

    # Minimal dimension of image
    p = min(Z.shape)

    # Greatest power of 2 less than or equal to p
    n = 2 ** np.floor(np.log(p) / np.log(2))

    # Extract the exponent
    n = int(np.log(n) / np.log(2))

    # Build successive box sizes (from 2**n down to 2**1)
    sizes = 2 ** np.arange(n, 1, -1)

    # Actual box counting with decreasing size
    counts = []
    for size in sizes:
        counts.append(boxcount(Z, size))

    # Fit the successive log(sizes) with log (counts)
    coeffs = np.polyfit(np.log(sizes), np.log(counts), 1)
    return -coeffs[0]
def FeatureCal(path, gap, pic_start, pic_end,  save_path):
    # def Feature(path, gap, pic_start, pic_end, gauss_para, median_para,feature,path_save):
    print(path)
    print(gap)
    print(pic_start)
    print(pic_end)

    avem = []
    aved = []
    avenum = []

    dissimilarity = []
    homogeneity = []
    ASM = []
    energy = []
    correlation = []
    fenxing = []

    for i in range(pic_start, pic_end + 1, gap):
        mixPath = path + '/gray-' + str(i) + '.png'
        print(mixPath)
        # False参数表示原图
        # rea = skimage.io.imread(mixPath, False)
        # True参数表示灰度图
        img = skimage.io.imread(mixPath, True)
        mark = img.copy()
        #img = exposure.equalize_adapthist(img, kernel_size=None, clip_limit=0.01, nbins=256)



        # 对二值图找出感兴趣去与
        contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
        # 在原图上绘制出感兴趣区域


        for i in contours:
            # print(cv2.contourArea(i))
            if cv2.contourArea(i) > 10:
                cv2.drawContours(mark, i, -1, (255, 0, 0), 7)
                # cv2.drawContours(mark,contours,-1,(255,0,0),5)

        # skimage.img_as_ubyte（image，force_copy）将图像转换为8位无符号整数格式。
        imgGray = skimage.img_as_ubyte(img, force_copy=False)

        binarypara = skimage.feature.greycomatrix(imgGray, [1], [0], levels=256)
        a = greycoprops(binarypara, 'contrast')
        b = greycoprops(binarypara, 'homogeneity')
        c = greycoprops(binarypara, 'ASM')
        d = greycoprops(binarypara, 'energy')
        e = greycoprops(binarypara, 'correlation')
        # f = graycoprops(binarypara, 'contrast')

        dissimilarity.append(a[0][0])
        homogeneity.append(b[0][0])
        ASM.append(c[0][0])
        energy.append(d[0][0])
        correlation.append(e[0][0])
        #fenxing.append(fractal_dimension(th2))

        avg = 0
        x = 0
        num = 0
        sum = 0
        for i in contours:
            x += cv2.contourArea(i)
            if x > 250:
                num += 1
                sum += x
        avg = x / num
        ad = ((4 * avg) / 3.14) ** 0.5
        print("ROI总面积为", x)
        print("当前图片中轮廓的个数为", len(contours))
        print("当前图片中轮廓的平均面积为", avg)
        print("当前图片中轮廓的平均直径为", ad)

        aved.append(ad)
        avem.append(avg)
        avenum.append(len(contours))

    data = pd.DataFrame()
    data['avem'] = avem
    data['aved'] = aved
    data['avenum'] = avenum
    data['dissimilarity'] = dissimilarity
    data['homogeneity'] = homogeneity
    data['ASM'] = ASM
    data['energy'] = energy
    data['correlation'] = correlation
    #data['fenxing'] = fenxing
    data.to_excel(save_path + '/excel.xlsx')
    # print(save_path)